import java.awt.*;
import java.util.Vector;

// This class represents vectors in a 3D vector space.
public class Vector3 {

    private double x;
    private double y;
    private double z;

    // default constructor
    public Vector3() {} // all values 0d by default

    // initialization constructor
    public Vector3(double x, double y, double z) {
        this.x = x; this.y = y; this.z = z;
    }

    /**
     * returns the sum of this vector and vector 'v'
     * @param v vector to be added
     * @return new Vector3 representing the sum
     */
    public Vector3 plus(Vector3 v) {
        return new Vector3(
                this.x + v.x,
                this.y + v.y,
                this.z + v.z
        );
    }

    /**
     * returns a copy of this vector scaled by 'd'
     * @param d scalar factor to be multiplied
     * @return new Vector3 as a result of vec * scalar
     */
    public Vector3 times(double d) {
        return new Vector3(
                this.x * d,
                this.y * d,
                this.z * d
        );
    }

    /**
     * returns the sum of this vector and inversion of vector 'v'
     * @param v vector to be inverted and added
     * @return new Vector3 representing the sum
     */
    public Vector3 minus(Vector3 v) {
        return new Vector3(
                this.x - v.x,
                this.y - v.y,
                this.z - v.z
        );
    }

    /**
     * returns the Euclidean distance of this vector to the specified
     * vector 'v'
     * @param v vector to calculate Euclidean distance to
     * @return double value representing sum of distances for each coordinate
     */
    public double distanceTo(Vector3 v) {
        double dx = Math.pow(this.x - v.x, 2d);
        double dy = Math.pow(this.y - v.y, 2d);
        double dz = Math.pow(this.z - v.z, 2d);
        return Math.sqrt(dx + dy + dz);
    }

    /**
     * returns the length (norm) of this vector
     * (which is really the Euclidean distance of this vector as a position
     * vector)
     * @return double value representing sum of distances for each coordinate
     * compared against 0d
     */
    public double length() {
        return this.distanceTo(new Vector3(0d, 0d, 0d));
    }

    /**
     * normalizes this vector by making its length equal the length of the
     * unit vector, while keeping orientation unchanged
     */
    public void normalize() {
        double length = this.length();
        this.x /= length;
        this.y /= length;
        this.z /= length;
    }

    /**
     * draws a filled circle centered at (x,y) coordinates of this vector
     * in an existing StdDraw canvas, z-coordinate remains unused
     * @param radius
     * @param color
     */
    public void drawAsDot(double radius, Color color) {
        StdDraw.setPenColor(color);
        StdDraw.filledCircle(this.x, this.y, radius);
    }

    /**
     * returns a formatted string containing the coordinates of this
     * vector using scientific notation in the following form:
     * "[x,y,z]", e.g., "[1.48E11,0.0,0.0]"
     * @return formatted string
     */
    @Override
    public String toString() {
        return String.format("[%g,%g,%g]", this.x, this.y, this.z);
    }

    /**
     * prints this vector to StdOut without a newline, in the format
     * specified by the toString directive
     */
    public void print() {
        System.out.print(this);
    }

}
